# -*- coding: utf-8 -*-

import random

def from_environ(environ, value, setter, *args, **kwargs):
    """
    Allows to run setter function if value does not exist in dictionary.
    Just returns value if it already exists.
    Setter arguments can be optionally specified after setter name.
    >>> environ = {}
    >>> def sum_setter(a, b=3):
    ...     return a+b
    >>> e = from_environ(environ, 'sum', sum_setter, 4, b=6)
    >>> print environ
    {'sum': 10}
    >>> print e
    10
    >>> e = from_environ(environ, 'sum', sum_setter, 10, b=50) # Nothing changed
    >>> print environ
    {'sum': 10}

    Also useful for making first-time values if they don't exist yet
    >>> some_list = from_environ(environ, 'empty_list', list, [1,2,3])
    >>> print environ
    {'empty_list': [1, 2, 3], 'sum': 10}
    """
    if not value in environ:
        if args:
            if kwargs:
                environ[value] = setter(*args, **kwargs)
            else:
                environ[value] = setter(*args)
        elif kwargs and not args:
            environ[value] = setter(**kwargs)
        else:
            environ[value] = setter()
    return environ[value]

def simple_app(environ, start_response):
    """A Hello-world WSGI application"""
    status = '200 OK'
    response_headers = [('Content-type','text/plain')]
    start_response(status, response_headers)
    return ['Hello world!\n']

def make_wsgi_chain(chain, orig_app):
	""" Wrap application with modules from the chain"""
	from middleware import classes
	from runner.runner import Runner
	rev_chain = list(chain)
	rev_chain.reverse() # Start from the end of chain, cause it's stack
	app = orig_app

	for (mw, params) in chain:
		if( mw in classes): # Built-in renyare middleware
			mwName = __import__('middleware', globals(), locals(), [classes[mw][0]])
			mwName = getattr(mwName, classes[mw][0])
			mwClass = getattr(mwName, classes[mw][1])
			app = mwClass(app, config=params)
		else: # Some external middleware
			app = Runner(mw, 'middleware', orig_app=orig_app, app_args=params)
	return app

def generate_password(length=6):
	res = ""
	for i in range(0, length):
		res += random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
	return res

def xmlify(text, tag="xml"):
	new_text = '<?xml version="1.0"?><xml><%s>' %tag
	for s in text.split('\n'):
		new_text += '<![CDATA[%s]]><br/>\n' % s
	new_text += '</%s></xml>' % tag
	return new_text

def wsgi2decorator(decorate):
	def decorator(**kwargs):
		def wrapped(app):
				try:
					deco = decorate(app, **kwargs) # application is middleware
				except TypeError:
					# Application is not middleware - we suppose it a simple wsgi application
					# If it is not so, WSGI wrapper will fail
					deco = decorate
				return deco
		return wrapped
	return decorator

class RenyareDebug:
	"""
	Provides debugging information handling
	"""
	def __init__(self, app, **kwargs):
		self.app = app
		self.level = kwargs.get('level') or None

	def new_response(self, status, headers):
		"""
		Displays debugging information on exit.
		"""
		status = '200 OK'
		self.start_response(status, headers)

	def __call__(self, environ, start_response):
		import log
		if(self.level):
			log.level = getattr(log.logging, self.level)
		for data in self.app(environ, start_response):
			yield data
		yield "<!--\n"
		yield "=================SOME DEBUG INFO\n<br/>"
		yield log.log_stream.getvalue()+"<br/>\n"
		for i in sorted(environ.keys()):
			yield str(i)+"="+str(environ[i])+"<br/>\n"
		yield "-->"

def _test():
    import doctest
    doctest.testmod()

if __name__ == "__main__":
    _test()
